home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Environments
/
RAMSES 2.2
/
RAMSES 2.2 Extras
/
Alpha Editor Support
/
Modula-2.tcl
< prev
next >
Wrap
Text File
|
1996-06-21
|
36KB
|
1,399 lines
####################################################################################
# #
# Modula.tcl: macros and bindings for Modula 2 programmers #
# #
# Usage: See "Modula Help" #
# #
# Programing: #
# First implementation was made by Juerg Thoeny <thoeny@ito.umnw.ethz.ch> #
# Further improvementes made by Andreas Fischlin <fischlin@ito.umnw.ethz.ch> #
# #
# Author Date Modification #
# ------ ---- ------------ #
# af 21.05.95 Initialization for new Alpha >= 6.0b7 fixed #
# All module templates fixed to behave usefully #
# af 01.09.95 Initialization for new Alpha >= 6.01 fixed #
# All module templates fixed to behave usefully #
# af 10.06.96 Fixed a few Modula-2 tcl bugs (see SysEcol #
# bug list) #
# af 24.06.96 Fixed a indentation and mark file bugs (see SysEcol #
# bug list) #
# #
# If you make improvements to this code, please send them to us! #
# via E-Mail: RAMSES@ito.umnw.ethz.ch #
# #
####################################################################################
# Global Alpha stuff
#set modMenu "•400"
set m2Menu "M2"
set M2CommentPreString "(*"
set M2CommentSufString "*)"
set modeMenus(M2) m2Menu
lappend allModeMenus m2Menu
lappend modeSuffixes {*.mod} { set winMode M2 }
lappend modeSuffixes {*.MOD} { set winMode M2 }
lappend modeSuffixes {*.def} { set winMode M2 }
lappend modeSuffixes {*.DEF} { set winMode M2 }
set M2modeVars(wordBreakPreface) {[^a-zA-Z0-9]}
set M2modeVars(wordBreak) {[a-zA-Z0-9]+}
set M2modeVars(elecRBrace) {0}
set M2modeVars(electricSemi) {0}
set M2modeVars(elecLBrace) {0}
set M2modeVars(wordWrap) {1}
set M2modeVars(prefixString) {(*}
set M2modeVars(suffixString) {*)}
set M2modeVars(funcExpr) {^[ |\t]*PROCEDURE[ ]*([a-zA-Z0-9]*)}
set M2modeVars(optionIsMeta) {1}
set M2modeVars(tagFile) "$HOME:modTAGS"
set M2modeVars(funcTitle) {PROC}
lappend modes M2
#buildModeFlagMenu
# Modula 2 stuff
# template bodys. Note, % means next line. To customize the template expansion, find the string
# "M2 TEMPLATES". Procedure and module templates are "directly coded". Be careful with customizing.
set templateBodys(CASE) " OF%| (*. .*):% (*. .*);%| (*. .*):% (*. .*);%ELSE% (*. .*);%END(*CASE*);"
set templateBodys(FOR) " := TO DO%END(*FOR*);"
set templateBodys(WHILE) " () DO%END(*WHILE*);"
set templateBodys(WITH) " DO%END(*WITH*);"
set templateBodys(REPEAT) "%UNTIL ();"
set templateBodys(IF) " THEN%ELSE%END(*IF*);"
set templateBodys(FROM) " IMPORT ;"
# This procedure will be called on the activate event.
proc handleM2ErrToken {} {
global M2TokenFile
if {[file exists "$M2TokenFile"]} {
source "$M2TokenFile"
removeFile "$M2TokenFile"
}
}
# configuration stuff
set defaultFont Programmer
set M2Loaded {0}
proc defineIndentation {} {
global M2RightShift
global M2LeftShift
set maxTabWidth 31
if {[info exists M2RightShift]} then {
set defltRIndent $M2RightShift
} else {
set defltRIndent " "
}
set Defltcount [string length $defltRIndent]
set prompt "By how many spaces shall «Tab»/«Shift right» move text?"
if {[catch {getline $prompt $Defltcount } count]} then {}
if {$count == ""} then {return}
set intCount ""
catch { set intCount [expr int($count)]}
if {$intCount == $count} then {
if {[expr (0 <= $intCount) & ($intCount <= $maxTabWidth)]} then {
# Now create the variables to make them accessible immediately
set M2RightShift ""
for {set i 0} {$i < $count} {incr i} {
set M2RightShift "$M2RightShift "
}
set M2LeftShift ""
for {set i 0} {$i < $count} {incr i; incr i} {
set M2LeftShift "$M2LeftShift "
}
if {($M2LeftShift == "") & ($M2RightShift != "")} then {
set M2LeftShift " "
}
addDef M2RightShift $M2RightShift
addDef M2LeftShift $M2LeftShift
set msg "«Tab»/«Shift right» shifts selection by [string length $M2RightShift],"
set msg "$msg «Shift left» shifts it by [string length $M2LeftShift] spaces."
alertnote $msg
} else {
alertnote "Please enter a number in range 0..$maxTabWidth"
catch { unset M2RightShift}
catch { unset M2LeftShift}
}
} else {
set msg "'$count' is not an integer!"
set msg "$msg Please enter a number in range 0..$maxTabWidth"
alertnote $msg
catch { unset M2RightShift}
catch { unset M2LeftShift}
}
}
proc defineWrapRightMargin {} {
global M2WrapRightMargin
set minWTRM 2
set maxWTRM 256
if {[info exists M2WrapRightMargin]} then {
set defltWTRM $M2WrapRightMargin
} else {
set defltWTRM 65
}
set prompt "At which right margin (column) shall text be wrapped?"
if {[catch {getline $prompt $defltWTRM } userWTRM]} then {}
if {$userWTRM == ""} then {return}
set intWTRM ""
catch { set intWTRM [expr int($userWTRM)]}
if {$intWTRM == $userWTRM} then {
if {[expr ($minWTRM <= $intWTRM) & ($intWTRM <= $maxWTRM)]} then {
# it's now ok
set M2WrapRightMargin "$userWTRM"
addDef M2WrapRightMargin $M2WrapRightMargin
} else {
alertnote "Please enter a number in range $minWTRM..$maxWTRM"
catch { unset M2WrapRightMargin}
}
} else {
set msg "'$M2WrapRightMargin' is not an integer!"
set msg "$msg Please enter a number in range $minWTRM..$maxWTRM"
alertnote $msg
catch { unset M2WrapRightMargin}
}
}
proc configureLaunching {} {
global M2Home
global M2TokenFile
global M2System
global M2ErrFile
global M2errDOKFile
global USER_STARTUP
set msg "Please configure the Modula-2 environment for the launching of a shell "
set msg "$msg and the compiler support."
alertnote $msg
if {[catch {getfile "Open a M2 shell (MacMETH or RAMSES)"} path]} then {
# immediately quit routine
return 1
}
set fileDir [file dirname $path]
addDef M2System $path
addDef M2Home $fileDir
addDef M2TokenFile "$fileDir:token.ALPHA"
addDef M2ErrFile "$fileDir:err.ALPHA"
# Now create the variables to make them accessible immediately
set M2System $path
set M2Home $fileDir
set M2TokenFile "$fileDir:token.ALPHA"
set M2ErrFile "$fileDir:err.ALPHA"
if {[catch {getfile "Locate 'ErrList.DOK' (look in ƒ M2Tools)"} errpath]} {
# immediately quit routine
return 1
}
addDef M2errDOKFile $errpath
# Now create the variable to make it accessible immediately
set M2errDOKFile $errpath
}
proc configure {} {
global M2Author
global M2RightShift
global M2WrapRightMargin
set prompt "Your first and last name please:"
if {[info exists M2Author]} then {
set defltUser $M2Author
} else {
set defltUser "First Last"
}
if {[catch {getline $prompt $defltUser } author]} then {}
if {$author == ""} then {return}
addDef M2Author $author
# Now create the variable to make it accessible immediately
set M2Author $author
# Now define indentation
defineIndentation
if {![info exists M2RightShift]} then {return}
# Now define right text wrap margin
defineWrapRightMargin
if {![info exists M2WrapRightMargin]} then {return}
}
# Make sure configuration is ok
if {[catch {set M2ConfTest "$M2System"}]} then {
configureLaunching
} elseif {![file exists "$M2System"]} then {
set shellName [file tail "$M2System"]
set quest "Could not find the Modula-2 shell “$shellName“. "
append quest "Do you wish to reconfigure the Modula-2 environment?"
if {[askyesno $quest] == "yes"} then {
configureLaunching
}
}
# Make sure M2Author is defined
while {![info exists M2Author]} {
configure
}
# Make sure M2RightShift is defined
while {![info exists M2RightShift]} {
defineIndentation
}
# Make sure M2WrapRightMargin is defined
while {![info exists M2WrapRightMargin]} {
defineWrapRightMargin
}
# Basic M2 binding to open work object
bind '0' <z> openM2WorkFiles
set returnCompleteWords "FOR FROM"
set returnWords "$returnCompleteWords BEGIN CONST ELSE WHILE IF PROCEDURE WITH"
set returnWords "$returnWords MODULE REPEAT TYPE VAR"
set spaceWords "CASE WHILE FOR IF REPEAT FROM PROCEDURE IMPLEMENTATION DEFINITION LOOP MODULE WITH"
set expandWords "ARRAY BOOLEAN BITSET CHAR CARDINAL DO END LONGCARD LONGINT LONGREAL"
set expandWords " $expandWords IMPORT INTEGER OF POINTER REAL RECORD RETURN TO"
set expandWords [lsort "$returnWords $spaceWords $expandWords"]
set m2ErrRing ""
# M2 KEY BINDINGS
bind '1' <z> launchShell
bind '2' <z> launchShellAndSimulate
bind '0' <z> openWorkFiles
bind 0x24 <s> carriageReturn "M2"
bind 0x24 modulaReturn "M2"
bind 0x31 modulaSpace "M2"
bind 0x33 <z> killWholeLine "M2"
bind 0x31 <e> expandSpace "M2"
bind 0x25 <e> markLine "M2"
bind 0x2e <z> markLine "M2"
bind 0x7c <z> forwardWord "M2"
bind 0x7b <z> backwardWord "M2"
bind 0x30 modulaTab "M2"
bind 0x73 <z> beginningOfBuffer "M2"
bind 0x77 <z> endOfBuffer "M2"
bind 'g' <z> nextPlaceholder "M2"
bind 'g' <sz> prevPlaceholder "M2"
bind '\]' <o> m2ShiftRight "M2"
bind 'r' <z> m2ShiftRight "M2"
bind '\[' <o> m2ShiftLeft "M2"
bind 'l' <z> m2ShiftLeft "M2"
bind 'k' <z> commentSelection "M2"
bind 'k' <sz> uncommentSelection "M2"
bind 'a' <sz> wrapText "M2"
bind 'a' <z> wrapComment "M2"
bind 0x33 <o> killLine "M2"
# 'M2' programming mode
proc setM2Mode {} {
changeMode "M2"
}
proc killWholeLine {} {
goto [lineStart [getPos]]
killLine
}
#================================================================================
proc actionOnReturn {} {
set pos [getPos]
deleteText $pos [selEnd]
goto $pos
endOfLine
carriageReturn
}
#================================================================================
proc modulaTab {} {
global M2RightShift
insertText $M2RightShift
}
proc wrapComment {} {
global leftFillColumn
global M2RightShift
global M2WrapRightMargin
global fillColumn
set increment [string length $M2RightShift]
set pos [getPos]
set end [selEnd]
if {$pos == $end} {
balance
set pos [getPos]
set end [selEnd]
if {$pos == $end} {
beep
message "Please make a selection"
return
}
}
set firstPos [lindex [search -s -r 1 -f 1 -n -- "\\(\\*" $pos] 0]
if {$firstPos == ""} {
beep
message "No comment in selection"
return
}
if {$firstPos > $end} {
beep
message "Empty selection?"
return
}
set lastPos [matchIt "\(" [expr $firstPos +$increment]]
if {$lastPos > $end} {
beep
message "Comment must be completely inside selection"
return
}
goto [expr $firstPos + $increment]
carriageReturn
set lastPos [matchIt "\(" [expr $firstPos +$increment]]
select [getPos] [expr $lastPos +1]
set tmpLeftFillColumn $leftFillColumn
set leftFillColumn [expr [lindex [posToRowCol $firstPos] 1] + $increment]
set tmpfillColumn $fillColumn
set fillColumn $M2WrapRightMargin
fillRegion
set leftFillColumn $tmpLeftFillColumn
set fillColumn $tmpfillColumn
goto [expr [matchIt "\(" [expr $firstPos +$increment]] -1]
carriageReturn
unIndent
set topTxtLeftMargRow [lindex [posToRowCol $firstPos] 0]
set topTxtLeftMargRow [expr $topTxtLeftMargRow +1]
set topTxtLeftMarg [rowColToPos $topTxtLeftMargRow 0]
set textBeg [expr [lindex [posToRowCol $firstPos] 1] + $increment]
set count [expr $textBeg]
goto $topTxtLeftMarg
for {set i 0} {$i < $count} {incr i} {
deleteChar
}
goto $firstPos
}
proc wrapText {} {
global leftFillColumn
global fillColumn
global M2WrapRightMargin
global fillColumn
set pos [getPos]
set end [selEnd]
if {$pos == $end} {
beep
message "Please make a selection"
return
}
set firstPos [search -s -r 1 -f 1 -n -- "\[\^ \\t\\r\]" $pos]
if {$firstPos > $end} {
beep
message "Empty selection?"
return
}
set tmpLeftFillColumn $leftFillColumn
set tmpfillColumn $fillColumn
set leftFillColumn [lindex [posToRowCol $firstPos] 1]
set fillColumn $M2WrapRightMargin
fillRegion
set leftFillColumn $tmpLeftFillColumn
set fillColumn $tmpfillColumn
set topTxtLeftMargRow [lindex [posToRowCol $firstPos] 0]
set topTxtLeftMarg [rowColToPos $topTxtLeftMargRow 0]
set textBeg [lindex [posToRowCol $firstPos] 1]
set count [expr $textBeg]
goto $topTxtLeftMarg
for {set i 0} {$i < $count} {incr i} {
deleteChar
}
goto $pos
}
#================================================================================
proc nextPlaceholder {} {
searchPlaceholder 1
}
proc prevPlaceholder {} {
searchPlaceholder 0
}
proc commentSelection {} {
set pos [getPos]
set end [selEnd]
if {$pos == $end} {
beep
message "Please make a selection"
return
}
replaceText $pos $end "\(\*\. [getText $pos $end] \.\*\)"
select $pos [expr $end + 8]
}
proc uncommentSelection {} {
set pos [getPos]
set end [selEnd]
if {$pos == $end} {
beep
message "Please make a selection"
return
}
if {[expr $end - $pos] < 8} {
beep
message "Selection to small"
return
}
if {[getText $pos [expr $pos + 4]] != "(*. "} {
beep
message "Wrong left comment-start in selection"
return
}
if {[getText [expr $end - 4] $end] != " .*)"} {
beep
message "Wrong right comment-start in selection"
return
}
replaceText [expr $end - 4] $end ""
replaceText $pos [expr $pos + 4] ""
select $pos [expr $end - 8]
}
#================================================================================
proc m2ShiftLeft {} {
global M2LeftShift
set start [lineStart [getPos]]
set end [nextLineStart [expr [selEnd] -1]]
set increment [string length $M2LeftShift]
for {set i $start} {$i < $end} {set i [nextLineStart $i]} {
if {[getText $i [expr $i + $increment]] != $M2LeftShift} {
beep
return
}
}
select $start $start
for {set i $start} {$i < $end} {set i [nextLineStart $i]} {
incr end -$increment
goto $i
replaceText $i [expr $i + $increment] ""
}
goto $start
select $start $end
}
#================================================================================
proc m2ShiftRight {} {
global M2RightShift
set start [lineStart [getPos]]
set end [nextLineStart [expr [selEnd] -1]]
select $start $start
set increment [string length $M2RightShift]
for {set i $start} {$i < $end} {set i [nextLineStart $i]} {
incr end $increment
goto $i
insertText $M2RightShift
}
goto $start
select $start $end
}
#================================================================================
proc searchPlaceholder {dir} {
set pos [getPos]
saveVars
set depth 1
if ($dir==1) {
set push "(*."
set pop ".*)"
if {[getSelect] != ""} {
incr pos
}
set add 3;
set position [search -s -r 1 -f $dir -n -- "\\(\\*\\." $pos]
} else {
set push ".*)"
set pop "(*."
set pos [expr [selEnd]-4]
set add -3;
set position [search -s -r 1 -f $dir -n -- "\\.\\*\\)" $pos]
}
if {$position != ""} {
set pos [expr "[lindex $position 0]+$add"]
set str "(\\(\\*\\.)|(\\.\\*\\))"
while {1} {
set limits [search -s -r 1 -f $dir -n -- "$str" $pos]
if {$limits == ""} {
message "Not matched placeholder"
beep
restoreVars
return
}
set pos [lindex $limits 0]
set c [getText $pos [expr "$pos+3"]]
if {$c == $push} {
incr depth
}
if {$c == $pop} {
if {[set depth [expr $depth-1]] == 0} {
if ($dir==1) {
select [lindex $position 0] [expr "$pos+3"]
} else {
select $pos [lindex $position 1]
}
restoreVars
return
}
}
set pos [expr $pos+$add]
if {$pos > [maxPos]} {
alertnote "makro error, please contact jth"
}
}
} else {
message "no more placeholders"
beep
}
restoreVars
}
#===========================================================================
# Modula routines.
#===========================================================================
menu -n $m2Menu {
"openWorkFiles"
"findNextError"
"launchShell"
"launchShellAndSimulate"
"(-"
"DefToMod"
"commentSelection"
"uncommentSelection"
"m2ShiftRight"
"m2ShiftLeft"
"wrapComment"
"wrapText"
"(-"
{menu -n templates -m {
"DEFINITION"
"FOR"
"IF"
"IMPLEMENTATION"
"PROCEDURE"
"MODULE"
"WHILE"
"WITH"
}
}
"configureLaunching"
"configure"
}
#================================================================================
proc fileExt {} {
set fileName [lindex [winNames -f] 0]
if {[string last "." $fileName] == -1} {
return " "
}
set fileName [split $fileName .]
return [lindex $fileName [expr "[llength $fileName]-1"]]
}
#================================================================================
proc removeM2ErrMarks {fileName} {
global m2ErrRing
while 1 {
set ind [lsearch $m2ErrRing "*$fileName*"]
if {$ind == "-1"} {
return
}
set m2ErrRing [lreplace $m2ErrRing $ind $ind]
}
}
#================================================================================
proc removeAllM2ErrMarks {} {
global m2ErrRing
while {[llength $m2ErrRing] != 0} {
removeTMark [lindex [lindex $m2ErrRing 0] 1]
set m2ErrRing [lreplace $m2ErrRing 0 0]
}
}
#================================================================================
proc actM2ErrMsg {} {
global m2ErrRing
global errList
beep
if {[llength $m2ErrRing] == "0"} {
message "No Modula errors"
beep
return
}
set num [lindex [lindex $m2ErrRing 0] 2]
regexp "$num\[ \]+(\[^\n\]*)" $errList dummyStr errMsg
set errMsg [string range $errMsg 0 40]
message $errMsg
}
#================================================================================
proc findNextError {} {
global m2ErrRing
global errList
set fileName [lindex [winNames -f] 0]
if {[llength $m2ErrRing] == "0"} {
beep
message "No more errors"
return
}
set first [lindex $m2ErrRing 0]
set m2ErrRing [lreplace $m2ErrRing 0 0]
set m2ErrRing [lappend m2ErrRing $first]
gotoTMark [lindex [lindex $m2ErrRing 0] 1]
if {$fileName != [lindex [winNames -f] 0]} {
centerRedraw
}
selectCurWord
actM2ErrMsg
}
#================================================================================
set loadM2ErrorMsg ""
proc openM2WorkFiles {} {
saveVars
global m2ErrRing
global errList
global M2ErrFile
global M2errDOKFile
global M2Home
global loadM2ErrorMsg
removeAllM2ErrMarks
set m2ErrRing ""
bind 'j' <z> findNextError "M2"
bind 'e' <z> findNextError "M2"
set loadM2ErrorMsg "opening or reading $M2errDOKFile"
set msgFile [open "$M2errDOKFile"]
set errList [read $msgFile]
close $msgFile
set loadM2ErrorMsg "opening or reading $M2ErrFile"
set errFile [open "$M2ErrFile"]
if {[gets $errFile lineStr] < 1} {
beep
message "No Errors found"
close $errFile
return
}
set numErrs 0
set i 1
while {$lineStr == "NEW"} {
if {[gets $errFile lineStr] < 1} {
break
}
set loadM2ErrorMsg "opening $lineStr"
set ind [lsearch [winNames -f] $lineStr]
if {$ind == -1} {
if {[file exists $lineStr]} {
edit "$lineStr"
} else {
edit "$M2Home$lineStr"
}
} else {
bringToFront [lindex [winNames] $ind]
}
set loadM2ErrorMsg "opening or reading $M2ErrFile"
if {[gets $errFile lineStr] < 1} {
break
}
set fileName [lindex [winNames -f] 0]
while {($lineStr != "NEW") && ($lineStr != "END")} {
scan $lineStr "%d %d" pos errNum
if {[gets $errFile lineStr] < 1} {
break
}
goto $pos
createTMark "errMark$i" $pos
set m2ErrRing [lappend m2ErrRing [list $fileName errMark$i $errNum]]
set i [expr $i+1]
set numErrs [expr $numErrs+1]
}
}
if {$numErrs < 1} {
beep
message "No Errors found"
close $errFile
return
}
close $errFile
gotoTMark errMark1
restoreVars
set pos [getPos]
centerRedraw
selectCurWord
actM2ErrMsg
}
proc openWorkFiles {} {
global loadM2ErrorMsg
if {[catch openM2WorkFiles]} {
beep
alertnote "Error: $loadM2ErrorMsg"
}
}
#================================================================================
proc callM2 {} {
global M2System
launch -f "$M2System"
}
proc launchShell {} {
if {[catch callM2]} {
beep
alertnote "Call of M2 went wrong.\rCheck configuration."
}
}
proc launchShellAndSimulate {} {
if {[catch callM2]} {
beep
alertnote "Call of M2 went wrong.\rCheck configuration."
}
dosc -n " RAMSES Shell 2.2b6" -k 'DMEv' -e 'COMP' -s "gaga" -r
}
#================================================================================
proc markLine {} {
set pos [getPos]
set start [lineStart $pos]
set end [nextLineStart $pos]
select $start $end
}
#================================================================================
proc trim {text} {
return [string trim $text]
}
#================================================================================
proc getCurLine {} {
set pos [getPos]
set start [lineStart $pos]
set end [nextLineStart $pos]
set text [getText $start $end]
regexp "(\[^\r\]*)\r?" $text dummyText text
return $text
}
#================================================================================
proc getCurWord {} {
set pos [getPos]
backwardWord
set bPos [getPos]
if {$bPos == 1} {
set text " "
regexp "\[A-Za-z\]" [getText 0 1] text
if {$text != " "} {
set bPos 0
}
}
forwardWord
set fPos [getPos]
goto $pos
return [getText $bPos $fPos]
}
#================================================================================
proc selectCurWord {} {
set pos [getPos]
set char [lookAt [expr "$pos-1"]]
if {[regexp "\[A-Za-z\]" $char] == 0} {
set bPos [expr "$pos+1"]
} else {
backwardWord
set bPos [getPos]
if {$bPos == 1} {
set text " "
regexp "\[A-Za-z\]" [getText 0 1] text
if {$text != " "} {
set bPos 0
}
}
forwardWord
}
select $bPos [getPos]
}
#================================================================================
proc firstWord {text} {
regexp "\[ |\t\]*(\[A-Za-z0-9_\]*)(.*)" $text text firstWd rest
return $firstWd
}
proc restWord {text} {
regexp "\[ |\t\]*(\[A-Za-z0-9_\]*)(.*)" $text text firstWd rest
return $rest
}
#================================================================================
proc initials {} {
global M2Author
return "[string index [lindex "$M2Author" 0] 0][string index [lindex "$M2Author" 1] 0]"
}
#================================================================================
proc unIndent {} {
global M2RightShift
set count [string length $M2RightShift]
for {set i 0} {$i < $count} {incr i} {
backSpace
}
}
# M2 TEMPLATES
#================================================================================
proc insertTemplateBody {name} {
global templateBodys
set pos [getPos]
set start [lineStart $pos]
set indent [eval "getText [join [search -s -r 1 -f 1 -n -- "\[ \\t\]*" $start]]"]
insertText [lindex [split "$templateBodys($name)" "%"] 0]
foreach bodyLine [lrange [split "$templateBodys($name)" "%"] 1 100] {
insertText \r${indent}${bodyLine}
}
goto $pos
}
#================================================================================
proc cASE {} {
insertText "CASE"
templateCASE
}
proc templateCASE {} {
insertTemplateBody CASE
goto [expr [getPos]+1]
}
#================================================================================
proc fOR {} {
insertText "FOR"
templateFOR
}
proc templateFOR {} {
insertTemplateBody FOR
goto [expr [getPos]+1]
}
#================================================================================
proc wHILE {} {
insertText "WHILE"
templateWHILE
}
proc templateWHILE {} {
insertTemplateBody WHILE
goto [expr [getPos]+2]
}
#================================================================================
proc wITH {} {
insertText "WITH"
templateWITH
}
proc templateWITH {} {
insertTemplateBody WITH
goto [expr [getPos]+1]
}
#================================================================================
proc iF {} {
insertText "IF"
templateIF
}
proc templateIF {} {
insertTemplateBody IF
goto [expr [getPos]+1]
}
#================================================================================
proc rEPEAT {} {
insertText "REPEAT"
templateREPEAT
}
proc templateREPEAT {} {
insertTemplateBody REPEAT
indentOnReturn
}
#================================================================================
proc fROM {} {
insertText "FROM"
templateFROM
}
proc templateFROM {} {
insertTemplateBody FROM
goto [expr [getPos]+1]
}
#================================================================================
proc pROCEDURE {} {
insertText "PROCEDURE"
templatePROCEDURE
}
proc templatePROCEDURE {} {
set winName [lindex [winNames -f] 0]
set procName [getline "PROCEDURE Name : "]
bringToFront $winName
if {[string length $procName] < 1} {
return;
}
set pos [expr "[getPos]+1+[string length $procName]"]
insertText " $procName;"
if {[string toupper [fileExt]] != "DEF"} {
carriageReturn
insertText "BEGIN (* $procName *)"
carriageReturn
insertText "END $procName;"
carriageReturn
}
goto $pos
}
#================================================================================
# An aux proc
proc askForModuleName {prompt} {
set modName [getline "$prompt"]
if {([string length $modName] < 1)} {
return ""
}
if {[regexp {[^A-Za-z0-9]} $modName]} then {
alertnote "The module name “$modName“ contains illegal characters!"
return ""
}
if {([string length $modName] > 12)} {
set quest "“$modName“ is too long (> 12 chars). You should stop to change it. Ok?"
if {[askyesno $quest] == "yes"} {
return ""
}
}
return $modName
}
proc openOrMakeFile {prompt ext} {
if {$prompt == ""} then {
set modName "$ext"
set modFName "$modName"
} else {
set modName [askForModuleName $prompt]
set modFName "$modName.$ext"
}
if {$modName == ""} then { return }
set winList [winNames]
if { [IsInList $winList $modFName] } then {
# File already exists and is open
bringToFront $modFName
} else {
# Create new file with the proper name
new -n $modFName
}
set modName [file tail $modFName]
set modName [file rootname $modName]
return $modName
}
#================================================================================
proc mODULE {} {
# Used by calling submenu M2/Templates/MODULE
set modName [openOrMakeFile "Program MODULE Name : " "MOD"]
if {$modName != ""} then {
insertText "MODULE"
modBODY $modName
}
}
proc templateMODULE {} {
# Used while expanding keyword MODULE
set modName [askForModuleName "Program MODULE Name: "]
if {$modName != ""} then {
modBODY $modName
}
}
#================================================================================
proc modBODY {modName} {
global M2RightShift
if {[string length $modName] < 1} {
return;
}
insertText " $modName;"
carriageReturn
carriageReturn
insertText $M2RightShift
insertText "(*"
carriageReturn
insertText $M2RightShift
insertText "Implementation and Revisions:"
carriageReturn
insertText "============================"
carriageReturn
carriageReturn
insertText "Author Date Description"
carriageReturn
insertText "------ ---- -----------"
carriageReturn
insertText "[initials] [format "%-11s" "[lindex [mtime [now] short] 0]"]"
insertText "First implementation"
carriageReturn
unIndent
insertText "*)"
carriageReturn
unIndent
set pos [getPos]
carriageReturn
insertText "BEGIN (* $modName *)"
carriageReturn
insertText "END $modName."
carriageReturn
goto $pos
indentOnReturn
}
#================================================================================
proc defBODY {modName} {
global M2RightShift
global M2Author
if {[string length $modName] < 1} {
return;
}
insertText " $modName;"
carriageReturn
carriageReturn
insertText $M2RightShift
insertText "(*******************************************************************"
carriageReturn
carriageReturn
insertText $M2RightShift
insertText "Module $modName (Version 1.0)"
carriageReturn
carriageReturn
insertText $M2RightShift
insertText "Copyright (c) 1992 by $M2Author and Swiss"
carriageReturn
insertText "Federal Institute of Technology Zurich ETHZ"
carriageReturn
carriageReturn
unIndent
insertText "Version written for:"
carriageReturn
insertText $M2RightShift
insertText "MacMETH_V3.2 (1-Pass Modula-2 implementation)"
carriageReturn
carriageReturn
unIndent
insertText "Purpose (*. purpose .*)"
carriageReturn
carriageReturn
insertText "Remarks (*. remarks .*)"
carriageReturn
carriageReturn
carriageReturn
insertText "Programming"
carriageReturn
carriageReturn
insertText $M2RightShift
insertText "o Design"
carriageReturn
insertText $M2RightShift
insertText "$M2Author [lindex [mtime [now] short] 0]"
carriageReturn
carriageReturn
unIndent
insertText "o Implementation"
carriageReturn
insertText $M2RightShift
insertText "$M2Author [lindex [mtime [now] short] 0]"
carriageReturn
carriageReturn
carriageReturn
unIndent
insertText "Swiss Federal Institute of Technology Zurich ETHZ"
carriageReturn
insertText "CH-8092 Zurich"
carriageReturn
insertText "Switzerland"
carriageReturn
carriageReturn
insertText "Last revision of definition: [lindex [mtime [now] short] 0] [initials]"
carriageReturn
carriageReturn
unIndent
unIndent
insertText "*******************************************************************)"
carriageReturn
carriageReturn
set pos [getPos]
unIndent
carriageReturn
insertText "END $modName."
carriageReturn
goto $pos
indentOnReturn
}
#================================================================================
proc defToMod {} {
set winName [lindex [winNames -f] 0]
if {$winName == ""} return
set modName [getText 0 [nextLineStart 0]]
if {[lindex $modName 0] != "DEFINITION"} {
beep
alertnote "wrong window"
return
}
if {[lindex $modName 1] != "MODULE"} {
beep
alertnote "wrong window"
return
}
set modName [lindex $modName 2]
set modName [string range $modName 0 [expr [string length $modName] - 2]]
if {$modName == ""} {
beep
alertnote "wrong window"
return
}
set modName [openOrMakeFile "" "$modName.MOD"]
insertText "IMPLEMENTATION MODULE "
modBODY $modName
set newName [lindex [winNames -f] 0]
unIndent
bringToFront $winName
set pos [search -s -r 1 -f 1 -i 0 -n -- "FROM|IMPORT" 0]
set end [search -s -r 1 -f 1 -i 0 -n -- "TYPE|PROCEDURE|VAR|CONST|END" 0]
if {$pos != ""} {
set text [getText [lineStart $pos] [lineStart $end]]
insertText -w $newName $text
}
set end 0
set matchStr "PROCEDURE\[ \\t\]*\[A-Za-z0-9\]+\[ \\t\]*(\\(\[^\\)\]*\\))?\[^\\;\]*\;"
set pos [search -s -r 1 -f 1 -i 0 -n -- $matchStr $end]
set end [lindex $pos 1]
while {$pos != "" } {
set text [getText [lineStart $pos] [nextLineStart [lindex $pos 1]]]
insertText -w $newName $text
set insertion [format "%[string first [lindex $text 0] $text]s" ""]
set procName [lindex [split "[lindex $text 1]" "(;"] 0]
insertText -w $newName $insertion
insertText -w $newName "BEGIN (* $procName *)"
insertText -w $newName "\r"
insertText -w $newName $insertion
insertText -w $newName "END $procName;"
insertText -w $newName "\r\r"
set pos [search -s -r 1 -f 1 -i 0 -n -- $matchStr $end]
set end [lindex $pos 1]
}
bringToFront $newName
changeMode "M2"
}
#================================================================================
proc dEFINITION {} {
# Used by calling submenu M2/Templates/DEFINITION
set modName [openOrMakeFile "DEFINITION MODULE Name: " "DEF"]
if {$modName != ""} then {
insertText "DEFINITION MODULE"
defBODY $modName
prevPlaceholder
prevPlaceholder
}
}
proc templateDEFINITION {} {
# Used while expanding keyword DEFINITION
insertText " MODULE"
set modName [askForModuleName "DEFINITION MODULE Name: "]
if {$modName != ""} then {
defBODY $modName
prevPlaceholder
prevPlaceholder
}
}
#================================================================================
proc iMPLEMENTATION {} {
# Used by calling submenu M2/Templates/IMPLEMENTATION
set modName [openOrMakeFile "IMPLEMENTATION MODULE Name : " "MOD"]
if {$modName != ""} then {
insertText "IMPLEMENTATION MODULE"
modBODY $modName
}
}
proc templateIMPLEMENTATION {} {
# Used while expanding keyword IMPLEMENTATION
set modName [askForModuleName "IMPLEMENTATION MODULE Name: "]
if {$modName != ""} then {
insertText " MODULE"
modBODY $modName
}
}
#================================================================================
proc indentOnReturn {} {
global M2RightShift
actionOnReturn
insertText $M2RightShift
}
#================================================================================
proc modulaReturn {} {
global returnWords
global returnCompleteWords
set line [getCurLine]
set first [firstWord $line]
set first [trim $first]
if {[lsearch " $returnWords " $first] > -1} {
if {[lsearch " $returnCompleteWords " $first] > -1} {
set pos [getPos]
set start [lineStart $pos]
set leftText [getText $start $pos]
if {$first == "FOR"} {
if {[string first "TO" $leftText] > -1} {
indentOnReturn
return
}
if {[string first ":=" $leftText] > -1} {
goto [expr "$start + [string first "TO" $line] + 3"]
return
}
if {[string first "FOR" $leftText] > -1} {
goto [expr "$start + [string first ":=" $line] + 3"]
return
}
goto [expr "$start + [string first "FOR" $line] + 4"]
}
if {$first == "FROM"} {
if {[string first "IMPORT" $leftText] > -1} {
actionOnReturn
return
}
if {[string first "FROM" $leftText] > -1} {
goto [expr "$start + [string first "IMPORT" $line] + 7"]
return
}
goto [expr "$start + [string first "FROM" $line] + 5"]
}
} else {
indentOnReturn
}
} else {
actionOnReturn
}
}
#================================================================================
proc modulaSpace {} {
global spaceWords
set line [getCurLine]
set first [firstWord $line]
set first [trim $first]
set rest [restWord $line]
set rest [trim $rest]
if {[lsearch " $spaceWords " $first] > -1} {
if {[string length $rest] > 0} {
deleteText [getPos] [selEnd]
insertText " "
} else {
if {[catch template$first]} {
beep
alertnote "Template for:$first not defined"
}
}
} else {
deleteText [getPos] [selEnd]
insertText " "
}
}
#================================================================================
proc expandSpace {} {
global expandWords
set pos [getPos]
backwardWord
set bPos [getPos]
if {$bPos == 1} {
set text " "
regexp "\[A-Za-z\]" [getText 0 1] text
if {$text != " "} {
set bPos 0
}
}
forwardWord
set fPos [getPos]
goto $pos
set origWord [getText $bPos $fPos]
set word [string toupper $origWord]
set ind [lsearch $expandWords $origWord*]
if {$ind == -1} {
wordCompletion
return
}
set expandWord [lindex $expandWords $ind]
if {$expandWord != $origWord} {
replaceText $bPos $fPos $expandWord
}
}
#================================================================================
proc M2MarkFile {} {
set pos 0
while {![catch {search -s -f 1 -r 1 -m 0 -i 0 {^[ \t]*PROCEDURE} $pos} res]} {
set start [expr [lindex $res 1] + 1]
set end [nextLineStart $start]
regexp "\[A-za-z\]*" [getText $start $end] text
set pos $end
set inds($text) [lineStart [expr $start - 1]]
}
if {[info exists inds]} {
foreach f [lsort [array names inds]] {
set next [nextLineStart $inds($f)]
setNamedMark $f $inds($f) $next $next
}
}
}
#================================================================================
# Colorize Modula code.
#================================================================================
regModeKeywords -b {(*} {*)} -c red -k blue M2 $expandWords
proc colorizeM2Comments {} {
}